home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / DSMODS / BEND.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-10  |  25.2 KB  |  1,053 lines

  1. /*****************************************************************************/
  2. /* HISTORY:                                     */
  3. /*                                         */
  4. /* 11/10/89  -  ins_slave() - Added cpabt = 0;                     */
  5. /*                      Problems resulted in that the routine doesn't  */
  6. /*                  clear the flag if no errors occur, thereby     */
  7. /*                  leaving the old state in the flag.         */
  8. /*****************************************************************************/
  9. #include    "defs.h"
  10. #include    "comp.h"
  11. #include    "cmd.h"
  12. #include     "osbind.h"
  13.  
  14. #define        MAXCMD        100        /* # commands in line    */
  15. #define        MAXCHR        800        /* # char/cmd in line    */
  16. #define        tsp        119        /* flash pos Thin SPace    */
  17. #define        nsp        120        /* flash pos eN   SPace    */
  18. #define        msp        121        /* flash pos eM   SPace    */
  19.  
  20. /*
  21.     Externals
  22. */
  23. extern    char        *realloc();
  24. extern    unsigned char    ptsfpos[256],
  25.             mcsdbl[303];        /* IFont Layout tables    */
  26. extern    struct slvll    *slv;            /* local GO slave list    */
  27. extern    int        vpage_size;        /* Vertical Page Size    */
  28.  
  29. /* ATARI */
  30. extern  int ptsarray[];
  31.  
  32. /*
  33.     Locals
  34. */
  35. static
  36. char        ker, ichfg, fhfg, rvofg;    /* some local flags    */
  37. static
  38. char        Kapp;                /* Kerning apply flag    */
  39. static
  40. int        splen;                /* space length holder    */
  41. static
  42. unsigned    spcnt, ispcnt, ccnt, cmdcnt;    /* various counters    */
  43. static
  44. unsigned    prepos;                /* PREvious char POS.    */
  45. static
  46. unsigned    ichcnt, ichwid,            /* Insert CHar. vars    */
  47.         ichpos[MAXCMD];
  48. static
  49. unsigned    rvopsiz, topval, botval,    /* Reverse Video vars    */
  50.         pvlsp, pvbot;
  51. static
  52. unsigned long    cmdrec[MAXCMD];            /* tag CoMmanD RECord    */
  53. static    struct {
  54.     unsigned char    acf;            /* floating accent flag    */
  55.     unsigned    pos;            /* position in chinln[]    */
  56. }    chs;                    /* CHar. State struct.    */
  57. static    struct {
  58.     unsigned char    fg;            /* char flag from font    */
  59.     unsigned char    ch;            /* its flash position    */
  60.     int        wid;            /* its composed width    */
  61. }    chinln[MAXCHR];                /* Char. IN LiNe array    */
  62.  
  63. /*
  64.     Globals
  65. */
  66. char        fofg;                /* Flash Only flag    */
  67. char        cpjm;                /* line justified mode    */
  68. char        advld, rldld;            /* Accumulative leading    */
  69. unsigned    disp;                /* Xdisplacement from 0    */
  70. unsigned char    *utinpt;            /* slave input pointer    */
  71. struct slvll    *Bslv;                /* Bend slave list ptr    */
  72. unsigned    init_x;                /* initial X from Atari    */
  73. unsigned long    init_y;                /* initial Y from Atari    */
  74. unsigned long    last_y;                /* Bend last Y known    */
  75. int        TYF_handle;            /* TYsetter file handle    */
  76. int        TYF_Gx0, TYF_Gy0;        /* Graphics file X0,Y0,    */
  77. int        TYF_Gx1, TYF_Gy1;        /* Graphics file X1,Y1,    */
  78. int        TYF_Gtype;            /* Graphics file type,    */
  79. char        *TYF_Gfile;            /* filename or cmd ptr    */
  80.  
  81.  
  82. /*
  83.     Justification & Slave generation processor.
  84.     Only called by dotext(). Returns pointer to next text
  85.     if cpabt is 0 or 8 else -1L for all other true values
  86.     of cpabt. Set
  87.     cpabt:    0    -- no error
  88.         4    -- line measure too short
  89.         7    -- no memory for tag support
  90.         8    -- Hit Region Feed
  91. */
  92. unsigned char    *bend(text,done)
  93. struct textobj    *text;
  94. int        *done;
  95. {
  96.     unsigned char    *inptr, c, noerr;
  97.  
  98.     cpabt = 0;
  99.     if (text->begtext >= free_start) {    /* no text return...    */
  100.         *done = 1;
  101.         return(-1L);
  102.     }
  103.     else    *done = 0;
  104.     setslvlist(text);            /* setup slave list    */
  105.     if (cpabt == 7)                /* memory error quit...    */
  106.         return(-1L);
  107.     initbcomp();                /* initialize Bend vars    */
  108.     inptr = text->begtext;            /* set text scan pter    */
  109.     while (!cpabt && inptr < free_start)    /* until end of buffer    */
  110.     switch(c = *inptr++) {
  111.     case ' ':                    /* space band    */
  112.         Kapp = 0;
  113.         cmpval = avcval = 0;            /* no CComp...    */
  114.         prepos = ccnt;
  115.         chinln[ccnt].fg = 0;
  116.         chinln[ccnt].ch = SPC;
  117.         splen += (chinln[ccnt++].wid    /* update space length    */
  118.               = cwfrw(spbval,0));    /* by min space band... */
  119.         ++spcnt;            /* update space counter    */
  120.         break;
  121.     case hrt:                    /* hard return    */
  122.     case srt:                    /* soft return    */
  123.     case Rf:                    /* Region Feed    */
  124.         if (line_ck())                /* final check    */
  125.             goto out;            /* error quit..    */
  126.         inptr += 2;                /* skip cr-lf    */
  127.         if (c == Rf)                /* Region Feed    */
  128.             cpabt = 8;            /* Stop now...    */
  129.         else
  130.         if (dpreset())                /* reach depth?    */
  131.             goto out;
  132.         break;
  133.     case cr:                    /* carr. return    */
  134.         ++inptr;                /* skip over lf    */
  135.         break;
  136.     case DH:                    /* disc. hyphen    */
  137.     case lf:                    /* line feed    */
  138.         break;                    /* ignore them    */
  139.     case QL:                    /* quad left    */
  140.         Kapp = 0;
  141.         cpjm = AL;
  142.         break;
  143.     case QR:                    /* quad right    */
  144.         Kapp = 0;
  145.         cpjm = AR;
  146.         break;
  147.     case QC:                    /* quad center    */
  148.         Kapp = 0;
  149.         cpjm = AC;
  150.         break;
  151.     case STAG:                    /* start TAG    */
  152.         in_tag(*inptr++,0,1);
  153.         cmpval = avcval = 0;            /* no CComp...    */
  154.         Kapp = 0;
  155.             break;
  156.     case ETAG:                    /* end    TAG    */
  157.         out_tag(*inptr++,0,1);
  158.         cmpval = avcval = 0;            /* no CComp...    */
  159.         Kapp = 0;
  160.             break;
  161.     case PTAG:                    /* PI TAG    */
  162.         storech(*inptr++);
  163.             break;
  164.     case sHY: case sDH:                /* soft hyphens    */
  165.         c = '-'; 
  166.     default:                    /* other chars    */
  167.         bcwidth(c);
  168.         break;
  169.     }
  170.     if (ccnt && !cpabt)            /* if there are chars..    */
  171.         line_ck();            /* final check on line    */
  172.  
  173. out:    funct_comm(SLVEOB,0);            /* place End Of Block    */
  174.     noerr = (!cpabt || cpabt == 8);
  175.     *done = (noerr && inptr >= free_start);
  176.     if (noerr) {
  177.         last_y = init_y + cdep;        /* save last Y known    */
  178.         Bslv->bufptr = realloc        /* reallocate slave...    */
  179.             (Bslv->bufptr,utinpt - Bslv->bufptr);
  180.     }
  181.     return(noerr ? inptr:(unsigned char *)-1L);
  182. }
  183.  
  184. /*
  185.     Routine to reset some composition parameters for new line
  186. */
  187. Lreset()
  188. {
  189.     disp    = init_x;
  190.     smsz    = cp.ssiz;
  191.     cpjm    = cp.jstmd;
  192.     ispcnt    = spcnt = ichcnt = cmdcnt = ccnt = cct = 0;
  193.     clen    = splen = ichwid = 0;
  194.     rvopsiz    = 0;
  195.     ichfg    = fhfg = 0;
  196.     chs.acf = 0;
  197.     chs.pos = 0;
  198.     Kapp    = 0;
  199.     cmpval  = avcval = 0;
  200. }
  201.  
  202. /*
  203.     Routine to intialize all default composition parameters
  204.     on entry to Bend()...
  205. */
  206. initbcomp()
  207. {
  208.     advld    = rldld = 0;
  209.     pvbot    = pvlsp = 0;
  210.     fofg    = 0;
  211.     spbval  = cp.minsp + cp.prfsp;        /* set space value...    */
  212.     cdep    = cp.lnsp;            /* set start depth    */
  213.     rvofg    = cp.rvomd;
  214.     Bslv    = slv;
  215.     utinpt    = Bslv->bufptr;            /* init slave pointer    */
  216.     Lreset();                /* reset line vars...    */
  217.     funct_comm(pt_typ,cp.ptsz);            /* setup point,    */
  218.     funct_comm(s_size,cp.ssiz);            /* set size    */
  219.     typeface(cp.font);            /* place Font info...    */
  220.     to_new_y();                /* place move FWD | REV    */
  221. }
  222.  
  223. /*
  224.     Routine to return current Char. Comp. value (Auto + Manual)
  225. */
  226. chcomp()
  227. {
  228.     int    temp = 0;
  229.  
  230.     if (cp.mcomp) {
  231.         temp += cmpval;
  232.         if (!chs.acf)
  233.             cmpval = cp.mcomp;
  234.     }
  235.     if (cp.acomp) {
  236.         temp += avcval;
  237.         if (!chs.acf)
  238.             avcval = acmp;
  239.     }
  240.     return(temp);
  241. }
  242.  
  243. /*
  244.     Routine to advance Bend depth
  245. */
  246. dpreset()
  247. {
  248.     if ((cdep + cp.lnsp) >= cp.depth)    /* break point reached    */
  249.         return(1);
  250.     else {
  251.         ad_dp();
  252.         Lreset();            /* reset for next line    */
  253.         return(0);
  254.     }
  255. }
  256.  
  257. /*
  258.     Function to do final line check (space justification and
  259.     slave generation)
  260. */
  261. line_ck()
  262. {
  263.     int    erf = 0;
  264.  
  265.     if (chs.acf) {                /* Faccent only at eol    */
  266.         ++cct;                    /* count it...    */
  267.         clen += chinln[chs.pos].wid;
  268.     }
  269.     if (cct || ichcnt)            /* some chars in line    */
  270.         erf = just_space(cp.llen-splen-clen);    /* go justify    */
  271.     else {                    /* or some cmds or none    */
  272.         if (rvofg)            /* check RVO to setup    */
  273.             set_rev_par();
  274.         if (cmdcnt)            /* if some cmds do them    */
  275.             funct_call(0,0,0,0);
  276.         if (rvofg)            /* check RVO to close    */
  277.             rev_video(OFF);
  278.     }
  279.     return(erf);
  280. }
  281.  
  282. /*
  283.     Function to justify extra space in line...
  284. */
  285. just_space(ex_sp)
  286. int    ex_sp;
  287. {
  288.     int    i, v, val, chct;
  289.     int    minlsp, maxlsp, cw;
  290.  
  291.     if (ichcnt) {                    /* IC cmd(s) ?    */
  292.       if (ex_sp < 0)                /* if no space    */
  293.         for (i = 0;i < ichcnt;++i)        /* find all ICs    */
  294.             chinln[ichpos[i]-1].fg = 0;    /* to disable..    */
  295.       else
  296.       if (ex_sp <= ichwid) {            /* enough space    */
  297.         for (i = 0;i < ichcnt;++i) {        /* for all ICs    */
  298.           cw = chinln[ichpos[i]].wid;        /* get IC width    */
  299.           if (cw <= ex_sp) {            /* space left ?    */
  300.             ex_sp -= cw;            /* (-) IC width    */
  301.             ichpos[i] = 1;            /* set min of 1    */
  302.           }
  303.           else    chinln[ichpos[i]-1].fg = 0;    /* or disable..    */
  304.         }
  305.         ichwid = 0;                /* no IC width    */
  306.       }
  307.     }
  308.  
  309.     if (cpjm != AJ &&            /* Non Justify mode and    */
  310.         ex_sp > 0 && !ispcnt && !ichcnt) {    /* extra space found..    */
  311.       if (cpjm == AR)                /* quad right    */
  312.         disp += ex_sp;                /* add to left    */
  313.       else
  314.       if (cpjm == AC)                /* quad center    */
  315.         disp += (ex_sp / 2);            /* add 1/2 only */
  316.     }
  317.  
  318.     if (rvofg)                /* check RVO to setup    */
  319.         set_rev_par();
  320.  
  321.     if (ex_sp < 0) {            /* Negative space case    */
  322.       if (!spcnt)                    /* no spaceband    */
  323.         v = minlsp = 0;                /* no (+) space    */
  324.       else {
  325.         v = cwfrw(cp.prfsp,1);            /* get Prf diff    */
  326.         minlsp = v * spcnt;            /* to (+) space    */
  327.       }
  328.       if ((ex_sp + minlsp) >= 0) {            /* Min|Prf range*/
  329.         ex_sp = ~ex_sp + 1;
  330.         funct_call(-(ex_sp/spcnt),-(ex_sp%spcnt),0,0);
  331.       }
  332.       else
  333.       if (cp.ltsmd && cp.nlts && cct > 1) {        /* LTSpace on    */
  334.         ex_sp += minlsp;            /* (+) space...    */
  335.         chct   = cct - 1;
  336.         minlsp = cwfrw(cp.nlts,1) * chct;    /* get LTS diff    */
  337.         if ((ex_sp + minlsp) >= 0) {        /* -LTS range    */
  338.           ex_sp = ~ex_sp + 1;
  339.           funct_call(-v,0,-(ex_sp/chct),-(ex_sp%chct));
  340.         }
  341.         else    cpabt = 4;            /* line overset    */
  342.       }
  343.       else    cpabt = 4;                /* line overset    */
  344.     }
  345.     else
  346.     if ((!ispcnt && !ichcnt) ||        /* no ISpace or IChar    */
  347.         ( ichcnt && !ichwid)) {        /* or IC being counted    */
  348.       if (cpjm == AJ && ex_sp && cct > 1) {    /* Justify & extra Sp    */
  349.         chct = cct - 1;
  350.         if (cp.plts) {                /* +LTS active    */
  351.           val = cwfrw(cp.plts,1);        /* get +LTS to    */
  352.           minlsp = val * chct;            /* spread extra    */
  353.         }
  354.         else
  355.           val = minlsp = 0;            /* no +LTS...    */
  356.         if (spcnt) {                /* Spacebands ?    */
  357.           v = cwfrw(cp.maxsp,1);        /* get MaxSp to    */
  358.           maxlsp = v * spcnt;            /* spread extra    */
  359.           if (    !cp.ltsmd ||            /* LTSpace off    */
  360.             ex_sp <= maxlsp  )        /* extra fit Sp    */
  361.                             /* spread to Sp    */
  362.             funct_call(ex_sp/spcnt,ex_sp%spcnt,0,0);
  363.           else {                /* +LTS range    */
  364.             ex_sp -= maxlsp;        /* take off Sp    */
  365.             if (ex_sp <= minlsp)        /* extra fit LTS*/
  366.                             /* spread to Ch    */
  367.               funct_call(v,0,ex_sp/chct,ex_sp%chct);
  368.             else {                /* extra > +LTS    */
  369.               ex_sp -= minlsp;
  370.               funct_call(v+(ex_sp/spcnt),ex_sp%spcnt,val,0);
  371.             }
  372.           }
  373.         }
  374.         else                    /* no space...    */
  375.         if (cp.ltsmd) {                /* LTSpace on    */
  376.           if (ex_sp < ((val *= 3) * chct))    /* extra <+3LTS    */
  377.             funct_call(0,0,ex_sp/chct,ex_sp%chct);
  378.           else    funct_call(0,0,val,0);        /* spread +3LTS    */
  379.               
  380.         }
  381.         else    funct_call(0,0,0,0);        /* just output    */
  382.       }
  383.       else    funct_call(0,0,0,0);        /* act as Non Justify    */
  384.     }
  385.     else
  386.     if (ex_sp > 0) {            /* Positive space case    */
  387.       if (ichcnt) {                /* there are IC(s)...    */
  388.         cw    = ex_sp / ichcnt;        /* spread to IC    */
  389.         val    = ex_sp % ichcnt;        /* extra remain    */
  390.         ex_sp    = 0;
  391.         for (i = 0;i < ichcnt;++i) {
  392.           if (val)
  393.             v = 1, --val;            /* use remain    */
  394.           else    v = 0;
  395.           if (    chinln[ichpos[i]].ch == msp ||    /* IC EM Space    */
  396.             chinln[ichpos[i]].ch == nsp ||    /* IC EN Space    */
  397.             chinln[ichpos[i]].ch == tsp  )    /* IC TH Space    */
  398.             chinln[ichpos[i]].wid = cw + v;
  399.           else {                /* IC normal Ch    */
  400.             if (chinln[ichpos[i]].wid) {    /* valid width    */
  401.               ex_sp += (chinln[ichpos[i]-1].wid =
  402.                  (cw+v)%chinln[ichpos[i]].wid);
  403.               if (cw)            /* set # of Ch    */
  404.                 ichpos[i]= (cw+v)/chinln[ichpos[i]].wid;
  405.             }
  406.             else { cpabt = 4; goto out; }    /* what ? error    */
  407.           }
  408.         }
  409.       }
  410.       if (ex_sp) {
  411.         if (ispcnt)                /* spread to IS    */
  412.             funct_call(ex_sp/ispcnt,ex_sp%ispcnt,0,0);
  413.         else
  414.         if (spcnt)                /* spread to Sp    */
  415.             funct_call(ex_sp/spcnt,ex_sp%spcnt,0,0);
  416.         else    funct_call(0,0,0,0);        /* all other Ch    */
  417.       }
  418.       else    funct_call(0,0,0,0);            /* just output    */
  419.     }
  420.     else    funct_call(0,0,0,0);        /* just output slave...    */
  421.  
  422. out:    if (rvofg)                /* check RVO to close    */
  423.         rev_video(OFF);
  424.     return(cpabt);
  425. }
  426.  
  427. /*
  428.     Slave generator and Extra space justificator
  429.     sw    : space width
  430.     ex_spw    : extra space remainder
  431.     cw    : LTS value on character
  432.     ex_chw    : extra LTS remainder
  433. */
  434. funct_call(sw,ex_spw,cw,ex_chw)
  435. int    sw, ex_spw, cw, ex_chw;
  436. {
  437.     int    i, j, k, l, v;
  438.  
  439.     i = k = l = 0;                    /* zero indexes    */
  440.  
  441.     while (i < ccnt && !cpabt) {        /* scan chinln[] for...    */
  442.  
  443.     if (chinln[i].ch == IC) {            /* Ins Char cmd    */
  444.       if (chinln[i].fg)                /* check valid    */
  445.       switch(chinln[++i].ch) {            /* check type    */
  446.       case SPC:                    /* word space    */
  447.         disp += (chinln[i].wid + sw);
  448.         if (ex_spw) {                /* space left..    */
  449.             --ex_spw;
  450.             ++disp;
  451.         }
  452.         break;
  453.       case msp: case nsp: case tsp:            /* fixed spaces    */
  454.         disp += chinln[i].wid;
  455.         ++k;                    /* bump ICcount    */
  456.         break;
  457.       default:                    /* other chars    */
  458.         if (chinln[i-1].wid && !ispcnt && !spcnt)
  459.         {                    /* space left..    */
  460.             v = chinln[i-1].wid % 2;
  461.                chinln[i-1].wid /= 2;
  462.             disp += (chinln[i-1].wid + v);
  463.         }
  464.         for (j = 0;j < ichpos[k];++j)
  465.         if (fhfg)                 /* no flash on    */
  466.             disp += chinln[i].wid;        /* skip width    */
  467.         else    long_char_for(chinln[i].ch,chinln[i].wid);
  468.         if (chinln[i-1].wid && !ispcnt && !spcnt)
  469.             disp += chinln[i-1].wid;    /* space left..    */
  470.         ++k;                    /* bump ICcount    */
  471.         break;
  472.       }
  473.       else    ++i;                    /* else skip it    */
  474.     }
  475.     else
  476.     if (chinln[i].ch == CMDCH) {            /* Tag commands    */
  477.       switch(chinln[i].wid) {
  478.       case 1:                    /* point size    */
  479.         funct_comm(pt_typ,(int)cmdrec[l]);
  480.         break;
  481.       case 2:                    /* set size    */
  482.         funct_comm(s_size,(int)cmdrec[l]);
  483.         break;
  484.       case 3:                    /* Font        */
  485.         typeface((int)cmdrec[l]);
  486.         break;
  487.       case 4:                    /* Adv leading    */
  488.         funct_comm(ver_mov_for,(int)cmdrec[l]);
  489.         break;
  490.       case 5:                    /* Rev leading    */
  491.         funct_comm(ver_mov_rev,(int)cmdrec[l]);
  492.         break;
  493.       case 6:                    /* Move Right    */
  494.         disp += (unsigned)cmdrec[l];
  495.         break;
  496.       case 7:                    /* Move Left    */
  497.         disp -= (unsigned)cmdrec[l];
  498.         break;
  499.       case 11:                    /* Rev. Video    */
  500.         if (cmdrec[l]) {
  501.             set_rev_par();
  502.             rvofg = ON;
  503.         }
  504.         else    rev_video(rvofg = OFF);
  505.         break;
  506.       case 14:                    /* Flash Only    */
  507.         fhfg = (char)cmdrec[l];
  508.         break;
  509.       }
  510.       ++l;                        /* next command    */
  511.     }
  512.     else
  513.     if (chinln[i].ch == SPC) {            /* word space    */
  514.       if (!ispcnt || sw < 0 || ex_spw < 0) {
  515.         if (ex_spw > 0)
  516.         {--ex_spw; ++chinln[i].wid;}
  517.         if (ex_spw < 0)
  518.         {++ex_spw; --chinln[i].wid;}
  519.         disp += (chinln[i].wid + sw);
  520.       }
  521.       else    disp += chinln[i].wid;
  522.     }
  523.     else {                        /* other chars    */
  524.       if (chinln[i].ch == msp ||
  525.           chinln[i].ch == nsp ||
  526.           chinln[i].ch == tsp) {            /* fixed spaces    */
  527.         if (!ispcnt) {
  528.           if (ex_spw > 0)
  529.           {--ex_spw; ++chinln[i].wid;}
  530.           if (ex_spw < 0)
  531.           {++ex_spw; --chinln[i].wid;}
  532.         }
  533.         disp += chinln[i].wid;
  534.       }
  535.       else {                    /* all others..    */
  536.         if (cw || ex_chw) {
  537.           if (chinln[i].fg & 0x04)        /* accent char    */
  538.             chinln[i].wid += (cw / 2);
  539.           else {                /* normal char    */
  540.             chinln[i].wid += cw;
  541.             if (ex_chw > 0)
  542.             {--ex_chw; ++chinln[i].wid;}
  543.             if (ex_chw < 0)
  544.             {++ex_chw; --chinln[i].wid;}
  545.           }
  546.         }
  547.         if (fhfg)                 /* no flash on    */
  548.             disp += chinln[i].wid;        /* skip width    */
  549.         else    long_char_for(chinln[i].ch,chinln[i].wid);
  550.       }
  551.     }
  552.  
  553.     ++i;                    /* next in chinln[]...    */
  554.     }                    /* end of scan loop...    */
  555.  
  556.     if (cp.rvomd && cct)
  557.         pvlsp = (unsigned)cp.lnsp;
  558.     else    pvbot = pvlsp = 0;
  559.     if (setp.omod == 2) {            /* for CG 8200 only    */
  560.         funct_comm(hor_mov_dir,1);
  561.         funct_comm(hor_pos,0);
  562.         funct_comm(hor_mov_dir,0);
  563.     }
  564. }
  565.  
  566. /*
  567.     Routine to setup Typeface info
  568. */
  569. typeface(ftn)
  570. int    ftn;
  571. {
  572.     if (ckfont(ftn)) {            /* set font pointer    */
  573.         loadrval();            /* load Rev Video vals    */
  574.         funct_comm(ty_face,ftn,pftpt+2);/* place font # command    */
  575.     }
  576. }
  577.  
  578. /*
  579.     Function to get flash position, store it then
  580.     calculate its width.
  581. */
  582. bcwidth(c)
  583. unsigned char    c;
  584. {
  585.     unsigned char    fp;
  586.     unsigned    i;
  587.  
  588.     if (c == TSP)                /* all fixed spaces...    */
  589.         fp = tsp;
  590.     else
  591.     if (c == NSP)
  592.         fp = nsp;
  593.     else
  594.     if (c == MSP)
  595.         fp = msp;
  596.     else    fp = ptsfpos[c];        /* get flash position    */
  597.     if (fp == 254) {            /* if doublet case...    */
  598.         for (i = 0;
  599.              i < 303 && mcsdbl[i] != c;    /* find it in table...    */
  600.              i += 3);
  601.         if (i >= 303) {            /* no match error...    */
  602.             chs.acf = 0;
  603.             return;
  604.         }
  605.         if (!storech(mcsdbl[i+1]))    /* do floating accent    */
  606.             return;
  607.         fp = mcsdbl[i+2];        /* then normal char.    */
  608.     }
  609.     storech(fp);
  610. }
  611.  
  612. /*
  613.     Routine to store flash position and calculate its width.
  614. */
  615. storech(fp)
  616. unsigned char    fp;
  617. {
  618.     if (fp > msp || !width(fp))
  619.         return(chs.acf = 0);
  620.     else    return(1);
  621. }
  622.  
  623. /*
  624.     Routine to calculate Bend character width.
  625. */
  626. width(fp)
  627. unsigned char    fp;
  628. {
  629.     int        cw, aw, kerval;
  630.     unsigned char    rw, *p;
  631.  
  632.     p = pftpt + 49 + (unsigned)fp * 2;    /* offset to get width    */
  633.     if ((rw = *p) != 0xff) {
  634.       cw = cwfrw(rw,0);
  635.       if (chs.acf) {
  636.         chs.acf = 0;
  637.         cw -= chcomp();
  638.         if (cw < 0) cw = 0;
  639.         kerval = bkerning(fp,1);
  640.         if (kerval)
  641.             subchwid(prepos,kerval);
  642.         prepos = ccnt;
  643.         aw = chinln[chs.pos].wid;
  644.         if (cw < aw) cw = aw;        /* Ch Width < Accent W    */
  645.         clen += (cw - aw);
  646.         chinln[ccnt   ].ch  = chinln[chs.pos].ch;
  647.         chinln[chs.pos].ch  = fp;    /* swap accent to 2nd    */
  648.         chinln[chs.pos].wid = (cw - aw) / 2;
  649.         chinln[ccnt   ].wid = cw - chinln[chs.pos].wid;
  650.         Kapp = 1;
  651.         ++cct;
  652.         ++ccnt;
  653.       }
  654.       else {
  655.         chinln[ccnt].fg = *(p + 1);
  656.         chs.acf = chinln[ccnt].fg & 0x04;    /* accent bit ?    */
  657.         chs.pos = ccnt;
  658.         cw -= chcomp();
  659.         if (cw < 0) cw = 0;
  660.         kerval = bkerning(fp,0);
  661.         if (fofg) {                /* flash only..    */
  662.           chinln[ccnt].wid = 0; 
  663.           if (!chs.acf)
  664.             fofg = 0;
  665.         }
  666.         else {
  667.           if (!chs.acf) {
  668.             if (kerval) {
  669.             clen -= kerval;
  670.             chinln[prepos].wid -= kerval;
  671.             if (chinln[prepos].wid < 0)
  672.                 chinln[prepos].wid = 0;
  673.             }
  674.           }
  675.           chinln[ccnt].wid = cw;
  676.           if (!ichfg) {
  677.             if (!chs.acf) {
  678.             ++cct;
  679.             prepos = ccnt;
  680.             Kapp = 1;
  681.             }
  682.             clen += chinln[ccnt].wid;
  683.           }
  684.           else {
  685.             ichwid += cw;
  686.             if (!chs.acf)
  687.             ichfg = 0;
  688.           }
  689.         }
  690.         chinln[ccnt++].ch= fp;
  691.       }
  692.       if (cp.rvomd && cp.ptsz > rvopsiz)
  693.         rvopsiz = cp.ptsz;
  694.       return(1);
  695.     }
  696.     else
  697.       return(0);
  698. }
  699.  
  700. char    bgetkerval(fp,mode)
  701. unsigned char    fp;
  702. int        mode;
  703. {
  704.     unsigned char    *ptr, v;
  705.     char        min = 127;
  706.     unsigned    i, found;
  707.  
  708.     if (!txkn)                /* no sector kerning    */
  709.         return(0);
  710.     ptr = pftpt + 289 + ((unsigned)fp * 4);
  711.     if (!Kapp)
  712.         ker = 0;
  713.     else
  714.     if (!mode)
  715.         ker ^= 1;
  716.     for (i = 0;i < 4;++i,++ptr) {
  717.       if (mode) {
  718.         if (kern[ker].rval[i] > (v = *ptr & 0x0f))
  719.         kern[ker].rval[i] = v;
  720.         if (kern[ker].lval[i] > (v = *ptr >> 4))
  721.         kern[ker].lval[i] = v;
  722.       }
  723.       else {
  724.         kern[ker].rval[i] = *ptr & 0x0f;
  725.         kern[ker].lval[i] = *ptr >> 4;
  726.       }
  727.     }
  728.     if (Kapp)
  729.     for (i = 0;i < 4;++i) {
  730.       if (ker) {
  731.         kern[0].rval[i] += kern[1].lval[i];
  732.         if (min > kern[0].rval[i])
  733.         min = kern[0].rval[i];
  734.       }
  735.       else {
  736.         kern[1].rval[i] += kern[0].lval[i];
  737.         if (min > kern[1].rval[i])
  738.         min = kern[1].rval[i];
  739.       }
  740.     }
  741.     else    return(0);
  742.     if (kpval)                /* if kern pair exist    */
  743.     for (    ptr = kpptr, i = found = 0;
  744.         i < kpval && !found;
  745.         ++i, ptr += 3    )
  746.     if (chinln[prepos].ch == *ptr && fp == *(ptr+1)) {
  747.         found = 1;
  748.         min += *(ptr+2);
  749.     }
  750.     return(min);
  751. }
  752.  
  753. bkerning(fp,mode)
  754. unsigned char    fp;
  755. int        mode;
  756. {
  757.     char    kval;
  758.  
  759.     if (!cp.kernmd)
  760.         return(0);
  761.     kval = bgetkerval(fp,mode);
  762.     if (kval) {
  763.       if (kval < 0) {
  764.         kval = ~kval + 1;
  765.         return(0 - cwfrw(kval,0));
  766.       }
  767.       else    return(cwfrw(kval,0));
  768.     }
  769.     else    return(0);
  770. }
  771.  
  772. subchwid(pos,val)
  773. int    pos, val;
  774. {
  775.     if (chinln[pos].fg & 0x04) {            /* accent bit ?    */
  776.         chinln[pos-1].wid -= (val / 2);
  777.         chinln[pos  ].wid -= (val - (val / 2));
  778.     }
  779.     else    chinln[pos].wid -= val;
  780.     if (chinln[pos].wid < 0)
  781.         chinln[pos].wid = 0;
  782.     clen -= val;
  783. }
  784.  
  785. loadrval()
  786. {
  787.     union {
  788.         unsigned char    arr[6];
  789.         unsigned    val[3];
  790.     } rvo;
  791.     f_move(pftpt + 45,rvo.arr,6);
  792.     topval = rvo.val[2] - rvo.val[0];    /* rvo top window value    */
  793.     botval = rvo.val[1] - rvo.val[2];    /* rvo bot window value    */
  794. }
  795.  
  796. ad_dp()
  797. {
  798.     cdep += cp.lnsp;                /* add LSpace    */
  799.     funct_comm(ver_mov_for,(unsigned)cp.lnsp);    /* move down    */
  800. }
  801.  
  802. rev_video(mode)
  803. int    mode;
  804. {
  805.     funct_comm(hor_pos,disp);
  806.     funct_comm(rev_typ,mode);
  807. }
  808.  
  809. set_rev_par()
  810. {
  811.     unsigned long    temp1, temp2;
  812.  
  813.     if (rvopsiz) {
  814.       temp1 = ((long)rvopsiz * (long)topval * 3L) / 2084L;
  815.       temp2 = ((long)rvopsiz * (long)botval * 3L) / 2084L;
  816.       if ((temp1 + (long)pvbot) <= (long)pvlsp) {
  817.         temp1 = (long)pvlsp - (long)pvbot;
  818.         temp2 = ((long)pvlsp / 2L) - (long)temp2;
  819.       }
  820.       funct_comm(rev_wind_top,(unsigned)temp1);
  821.       funct_comm(rev_wind_bot,(unsigned)temp2);
  822.       pvbot = (unsigned)temp2;
  823.     }
  824.     else {
  825.       funct_comm(rev_wind_top,0);
  826.       funct_comm(rev_wind_bot,0);
  827.     }
  828.     rev_video(ON);
  829. }
  830.  
  831. static    to_new_y()
  832. {
  833.     unsigned long    new_y;
  834.  
  835.     new_y = init_y + cp.lnsp;
  836.     if (new_y > last_y)
  837.         funct_comm(ver_mov_for,
  838.             (unsigned)(new_y - last_y));    /* move forward    */
  839.     else
  840.     if (new_y < last_y)
  841.         funct_comm(ver_mov_rev,
  842.             (unsigned)(last_y - new_y));    /* move bckward    */
  843. }
  844.  
  845. in_cmmd(funct,arg)
  846. int        funct;
  847. unsigned long    arg;
  848. {
  849.     chinln[ccnt  ].fg    = 0;
  850.     chinln[ccnt  ].ch    = CMDCH;    /* store Tag command    */
  851.     chinln[ccnt++].wid    = funct;    /* store functN type    */
  852.     cmdrec[cmdcnt++]    = arg;        /* store Tag argument    */
  853. }
  854.  
  855. IC_cmd(ch,fpmode)
  856. unsigned char    ch, fpmode;
  857. {
  858.     chinln[ccnt].fg  = 1;
  859.     chinln[ccnt].ch  = IC;            /* store IC command    */
  860.     chinln[ccnt].wid = 0;            /* no width for IC cmd    */
  861.     if (!fpmode && ch == ' ') {
  862.         ++ccnt;
  863.         ++ispcnt;
  864.         chinln[ccnt].ch  = SPC;        /* store SPC (space)    */
  865.         chinln[ccnt++].wid = 0;        /* no width for IC cmd    */
  866.     }
  867.     else {
  868.         ichpos[ichcnt++] = ++ccnt;    /* pos to be inserted    */
  869.         cmpval = avcval = 0;        /* no CComp for IChar    */
  870.         ichfg = 1;            /* set IC flag before    */
  871.         if (fpmode)
  872.             storech(ch);
  873.         else    bcwidth(ch);        /* setting up ch width    */
  874.     }
  875. }
  876.  
  877. static    BEfct0()
  878. {
  879.     int    i;
  880.  
  881.     i = setp.omod;
  882.     i <<= 8;
  883.     i += get_pgtype();
  884.     funct_comm(st_take,i);            /* place Start of Take    */
  885.     funct_comm(USRPGN,1);            /* place Start Page #    */
  886.     funct_comm(SLVEOB,0);            /* place End Of Block    */
  887.     last_y = 0L;
  888. }
  889.  
  890. static    BEfct1()
  891. {
  892.     funct_comm(SLVEOD,0);            /* place End Of Data    */
  893. }
  894.  
  895. static    BEfct2()
  896. {
  897.     if (last_y > 0)                /* move to top page    */
  898.         funct_comm(ver_mov_rev,(unsigned)last_y);
  899.     funct_comm(SLVEOB,0);            /* place End Of Block    */
  900.     last_y = 0L;
  901. }
  902.  
  903. static    BEfct3()
  904. {
  905.     funct_comm(next_pg,0);            /* use GOG next page    */
  906.     funct_comm(SLVEOB,0);            /* place End Of Block    */
  907.     last_y = 0L;
  908. }
  909.  
  910. static    BEfct4()                /* For graphics mode 5    */
  911. {
  912.     funct_comm(graphic,TYF_Gtype);        /* insert VP command    */
  913.     funct_comm(SLVEOB,0);            /* place End Of Block    */
  914. }
  915.  
  916. static    BEfct5()                /* For other gr. modes    */
  917. {
  918.     int    fbuff[5];
  919.  
  920.     funct_comm(graphic,TYF_Gtype);        /* insert VP command    */
  921.     fbuff[0] = strlen(TYF_Gfile) + 11;    /* place count    */
  922.     fbuff[1] = TYF_Gx0;            /* place x0    */
  923.     fbuff[2] = TYF_Gy0;            /* place y0    */
  924.     fbuff[3] = TYF_Gx1 - TYF_Gx0 + 1;    /* place Width    */
  925.     fbuff[4] = TYF_Gy1 - TYF_Gy0 + 1;    /* place Height    */
  926.     movcmds(fbuff,10);
  927.     movcmds(TYF_Gfile,fbuff[0] - 10);    /* place filename    */
  928.     funct_comm(SLVEOB,0);            /* place End Of Block    */
  929. }
  930.  
  931. static    ins_slave(fct)
  932. int    (*fct)();
  933. {
  934.     struct textobj    temp;
  935.  
  936.     cpabt = 0;
  937.     temp.slvlist = (struct slvll *)0;
  938.     setslvlist(&temp);
  939.     if (cpabt)
  940.         return(0);
  941.     Bslv    = slv;
  942.     utinpt    = Bslv->bufptr;            /* init slave pointer    */
  943.  
  944.     (*fct)();                /* do slave function    */
  945.  
  946.     if (cpabt)
  947.         return(0);
  948.     else    return(writeslv(temp.slvlist));
  949. }
  950.  
  951. Start_TYF()
  952. {
  953.     return(ins_slave(BEfct0));
  954. }
  955.  
  956. End_TYF()
  957. {
  958.     return(ins_slave(BEfct1));
  959. }
  960.  
  961. topPge_TYF()
  962. {
  963.     return(ins_slave(BEfct2));
  964. }
  965.  
  966. newPge_TYF()
  967. {
  968.     return(ins_slave(BEfct3));
  969. }
  970.  
  971. insGR_TYF(op,count,glgrattr)
  972. int    op, count;
  973. int    glgrattr[];
  974. {
  975.     int    fbuff[7];
  976.  
  977.     if (TYF_Gtype == 5) {            /* For graphics mode 5    */
  978.       if (!ins_slave(BEfct4))        /* insert VP command    */
  979.         return(0);
  980.       fbuff[0] = 36 + (4 * count);    /* count  + x0 + y0 + width +    */
  981.                       /* height + op + pts count +    */
  982.                     /* glgrattr + points        */
  983.       fbuff[1] = TYF_Gx0;            /* place x0    */
  984.       fbuff[2] = TYF_Gy0;            /* place y0    */
  985.       fbuff[3] = TYF_Gx1 - TYF_Gx0 + 1;    /* place Width    */
  986.       fbuff[4] = TYF_Gy1 - TYF_Gy0 + 1;    /* place Height    */
  987.       fbuff[5] = op;            /* place opcode    */
  988.       fbuff[6] = count;
  989.       Fwrite(TYF_handle,14L,fbuff);
  990.       Fwrite(TYF_handle,22L,glgrattr);
  991.       Fwrite(TYF_handle,(long)(4L*(long)count),ptsarray);
  992.       return(1);
  993.     }
  994.     else    return(ins_slave(BEfct5));
  995. }
  996.  
  997. writeslv(slvlist)
  998. struct    slvll    *slvlist;
  999. {
  1000.     struct    slvll    *slvptr = slvlist;
  1001.     int        cnt, retc = 1;
  1002.  
  1003.     if (slvptr != (struct slvll *)0L) {
  1004.       for (;;) {
  1005.         cnt = countslaveB(slvptr->bufptr);
  1006.         if (cnt && write(TYF_handle,slvptr->bufptr,cnt) != cnt)
  1007.         {    retc = 0; break;    }
  1008.         if (slvptr->fptr == (struct slvll *)0L)
  1009.             break;
  1010.         else    slvptr = slvptr->fptr;
  1011.       }
  1012.       freeslvlist(slvlist);
  1013.     }
  1014.     return(retc);
  1015. }
  1016.  
  1017. /*
  1018. */
  1019. countslaveB(sptr)
  1020. unsigned char    *sptr;
  1021. {
  1022.     unsigned char    command, *eptr;
  1023.     unsigned    code, brk, cmd_len, cnt;
  1024.  
  1025.     brk = cnt = 0;
  1026.     eptr = sptr + UTSIZE;
  1027.     do {
  1028.       code = get_argument(sptr);    /* get encoded word    */
  1029.       if (!(code & 0xFF00))        /* check if NULL cmd    */
  1030.         cmd_len = 1;
  1031.       else    cmd_len = 3;
  1032.       if ((code & 0x8080) == 0x8080) {
  1033.         command = *sptr & 0x7f;
  1034.         switch (command) {
  1035.         case (SLVEOD):            /* end of data    */
  1036.         brk = 1;    break;
  1037.         case (SLVEOB):            /* end of block    */
  1038.         brk = 2;    break;
  1039.         case (ty_face):            /* font command    */
  1040.         cmd_len = 9;    break;
  1041.         case (graphic):            /* VP command    */
  1042.         if (*(sptr+2) < 5)
  1043.           cmd_len += get_argument(sptr+3);
  1044.         break;
  1045.         }
  1046.       }
  1047.       sptr += cmd_len;
  1048.       if (brk != 2)
  1049.         cnt += cmd_len;
  1050.     } while (!brk && sptr < eptr);
  1051.     return(cnt);
  1052. }
  1053.